package com.lmx.persistence.service;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.repoDomain.tmodel.Privilege;

/**
 * #{description} 支付记录接口
 *
 * @author shen
 * @version 1.00
 */
@Service
@Scope("prototype")
public class PrivilegeService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;
	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	protected GenericService dslJpaService;

	public void setDslJpaService(GenericService dslJpaService) {
		this.dslJpaService = dslJpaService;
	}

	protected JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	/*
	 * 定制save方法，处理序号和mask的业务逻辑
	 */
	public Privilege savePrivilege(Privilege privilege) {
		// 如果删除标志是1，则进行删除操作
		if (privilege.getDelStatus().intValue() == 1) {
			// 取得所有对应此权限和下级权限，删除对应的租户权限和角色权限
			String roleDelSql = "delete from t_s_role_function where function_id in "
					+ "(select id from t_s_function where remark LIKE '"
					+ privilege.getRemark() + "%')";
			String tenantDelSql = "delete from tnb_tenant_privilege where privilege_id in "
					+ "(select id from t_s_function where remark LIKE '"
					+ privilege.getRemark() + "%')";
			getJdbcTemplate().execute(roleDelSql);
			getJdbcTemplate().execute(tenantDelSql);
			// 然后删除本权限和所有下级权限
			String delSql = "delete from t_s_function where remark LIKE '"
					+ privilege.getRemark() + "%'";
			getJdbcTemplate().execute(delSql);
			return null;
		}
		// 默认机构
		if (privilege.getSystemType() == null) {
			privilege.setSystemType(ICommonConstants.SYSTEM_TYPE_JIGOU_1);
		}
		// 根据修改后的信息，判断序号是否有变化，如果有，进行序号和掩码的重排处理
		String sql = null;
		// 如果有上级，则查所有上级相同以及序号相同的数据
		if (privilege.getParent() != null
				&& privilege.getParent().getId() != null) {
			sql = "select * from t_s_function where parentfunctionid="
					+ privilege.getParent().getId().toString()
					+ " and functionorder=" + privilege.getOrder()
					+ " and functionlevel=" + privilege.getLevel();
		} else {
			sql = "select * from t_s_function where functionorder="
					+ privilege.getOrder() + " and functionlevel="
					+ privilege.getLevel();
		}
		List<Map<String, Object>> dataListTemp = getJdbcTemplate()
				.queryForList(sql);
		String parentRemark = null;
		// 取得上级掩码
		if (privilege.getParent() != null
				&& privilege.getParent().getId() != null) {
			parentRemark = getJdbcTemplate().queryForObject(
					"select remark from t_s_function where id="
							+ privilege.getParent().getId().toString(),
					String.class);
		}
		String oriRemark = this.buildMarkWithOrder(privilege.getOrder(),
				parentRemark);
		privilege.setRemark(oriRemark);
		if (privilege.getId() == null) {

			dslJpaService.create(privilege);
		} else {
			// 取得原来的order和父级id
			Integer order = getJdbcTemplate().queryForObject(
					"select functionorder from t_s_function where id="
							+ privilege.getId().toString(), Integer.class);
			Long parentid = getJdbcTemplate().queryForObject(
					"select parentfunctionid from t_s_function where id="
							+ privilege.getId().toString(), Long.class);
			dslJpaService.update(privilege);
			// 如果序号改变，则需要把下级序号重排 ,暂时先不实现
			// TODO
			// 如果上级权限改变了，应该改变所有下级的掩码
			Integer maskLen = oriRemark.length();
			if (order.intValue() != privilege.getOrder().intValue()) {
				String uptChildSql = "update t_s_function set remark=concat('"
						+ privilege.getRemark()
						+ "',right(remark,length(remark)-" + maskLen
						+ ")) where remark " + "LIKE '" + privilege.getRemark()
						+ "%' and id<>" + privilege.getId().toString();
				getJdbcTemplate().execute(uptChildSql);
			}
		}
		// 如果没有重的，则只计算掩码
		if (dataListTemp.size() < 1) {
			String remark = null;
			if (privilege.getParent() != null
					&& privilege.getParent().getId() != null) {
				remark = this.buildMarkWithOrder(privilege.getOrder(),
						parentRemark);
			} else {
				remark = this.buildMarkWithOrder(privilege.getOrder(), null);
			}
			return privilege;
		} else {
			// 如果有重的，需要重新排列后续所有序号和掩码
			String filterSql = null;
			// 首先拿到所有需要重排的本级记录
			if (privilege.getParent() != null
					&& privilege.getParent().getId() != null) {
				filterSql = "select * from t_s_function where parentfunctionid="
						+ privilege.getParent().getId().toString()
						+ " and functionorder>="
						+ privilege.getOrder()
						+ " and id<>"
						+ privilege.getId().toString()
						+ " and functionlevel=" + privilege.getLevel();
			} else {
				filterSql = "select * from t_s_function where functionorder>="
						+ privilege.getOrder() + " and id<>"
						+ privilege.getId().toString() + " and functionlevel="
						+ privilege.getLevel();
			}
			List<Map<String, Object>> resortList = getJdbcTemplate()
					.queryForList(filterSql);
			logger.debug("resortList size:" + resortList.size());
			for (int i = 0; i < resortList.size(); i++) {
				Map<String, Object> item = resortList.get(i);
				String maskOri = item.get("remark").toString();
				String maskTarget = this.addMaskNumber(item, parentRemark);
				// 逐条修改本级的序号和掩码
				String uptSql = "update t_s_function set functionorder=functionorder+1, remark='"
						+ maskTarget
						+ "' where id="
						+ item.get("id").toString();
				getJdbcTemplate().execute(uptSql);
				int maskLen = maskTarget.length();
				// 批量修改所有下级的掩码
				String uptChildSql = "update t_s_function set remark=concat('"
						+ maskTarget + "',right(remark,length(remark)-"
						+ maskLen + ")) where remark " + "LIKE '" + maskOri
						+ "%' and length(remark)>" + maskLen;
				getJdbcTemplate().execute(uptChildSql);
			}
		}
		return privilege;
	}

	public List<Privilege> getJujiaPrivilege() {
		return this.getSysPrivilege(ICommonConstants.SYSTEM_TYPE_JUJIA_2);
	}

	public List<Privilege> getJiGouPrivilege() {
		return this.getSysPrivilege(ICommonConstants.SYSTEM_TYPE_JIGOU_1);
	}

	/**
	 * 获取不同系统的全部权限
	 *
	 * @author ytche
	 * @param systemType
	 * @return
	 * @date 2017年5月18日 下午4:08:29
	 */
	@SuppressWarnings("unchecked")
	public List<Privilege> getSysPrivilege(Integer systemType) {
		List<Privilege> rtn = Lists.newArrayList();
		StringBuilder sb = new StringBuilder(
				"select p from Privilege as p where (type =1 or type = 3) and ")
				.append("systemType = ?1 and delStatus = 0");
		rtn = this.em.createQuery(sb.toString()).setParameter(1, systemType)
				.getResultList();
		return rtn;
	}

	// 根据序号生成掩码
	private String buildMarkWithOrder(Integer order, String parentRemark) {
		String remark = order.toString();
		if (remark.length() == 1) {
			remark = "00" + remark;
		}
		if (remark.length() == 2) {
			remark = "0" + remark;
		}
		if (parentRemark != null) {
			remark = parentRemark + remark;
		}
		return remark;
	}

	// 生成累加掩码
	private String addMaskNumber(Map<String, Object> item, String parentRemark) {
		Integer order = new Integer(item.get("functionorder").toString());
		order = order.intValue() + 1;
		return this.buildMarkWithOrder(order, parentRemark);
	}

	/**
	 * 获取指定tenant的权限
	 *
	 * @author ytche
	 * @param tenantId
	 * @date 2017年7月20日 下午1:55:24
	 */
	public List<Privilege> getPrivilegeByTenantId(Long tenantId) {
		String queryStr = "from Privilege as p where p.tenant.id=:tenantId "
				+ "and p.delStatus=0 and (p.type=1 or p.type=3)";
		return this.em.createQuery(queryStr).setParameter("tenantId", tenantId)
				.getResultList();
	}

	/**
	 * 获取所有未删除的权限
	 *
	 * @author ytche
	 * @return
	 * @date 2017年8月2日 上午10:43:38
	 */
	public List<Privilege> findNotDelete() {
		String queryStr = "from Privilege as p where p.delStatus=0 ";
		return this.em.createQuery(queryStr).getResultList();
	}

}
